package com.bluedot.www.core.service;


import com.bluedot.www.core.common.HandwritingRuntimeException;
import com.bluedot.www.core.dao.Execute;
import com.bluedot.www.core.pojo.DO.Customer;
import com.bluedot.www.core.pojo.DO.FamilyNumber;
import com.bluedot.www.core.pojo.DTO.CustomerDTO;
import com.bluedot.www.core.pojo.DTO.CustomerHistoryDTO;
import com.bluedot.www.core.pojo.DTO.ReportHistoryDTO;
import com.bluedot.www.core.pojo.VO.ViewCustomerInfo;
import com.bluedot.www.core.utils.DbUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author zhouxuan
 * @since 2021-08-07
 */
public class CustomerService {
    private static final String CUSTOMER_MAPPER_ADDRESS = "com.bluedot.www.core.mapper.xml.CustomerMapper.";

    private static final String FAMILY_NUMBER_MAPPER_ADDRESS = "com.bluedot.www.core.mapper.xml.FamilyNumberMapper.";

    public static Object execute(String methodName, Object[] param) {
        CustomerService customerService = new CustomerService();
        Object result = null;
        switch (methodName) {
            case "findById":
                result = customerService.findById((Long) param[0]);
                break;
            case "insertCustomer":
                result = customerService.insertCustomer((Customer) param[0]);
                break;
            case "deleteCustomer":
                result = customerService.deleteCustomer((List<Long>) param[0]);
                break;
            case "updateCustomer":
                result = customerService.updateCustomer((Customer) param[0]);
                break;
            case "moveCustomer":
                result = customerService.moveCustomer((List<Long>) param[0], (Long) param[1]);
                break;
            case "countCustomer":
                result = customerService.countCustomer((Long) param[0]);
                break;
            case "findCustomerById":
                result = customerService.findCustomerById((Long) param[0]);
                break;
            case "queryCustomerHistory":
                result = customerService.queryCustomerHistory((Long) param[0], (Integer) param[1]);
                break;
            case "updateCustomerStatus":
                result = customerService.updateCustomerStatus((Long) param[0], (Integer) param[1]);
                break;
            case "updateCustomerStatusList":
                result = customerService.updateCustomerStatusList((List<Long>) param[0]);
                break;
            default:
                throw new HandwritingRuntimeException(20005, "Method not found, method name: " + methodName);
        }
        return result;
    }


    /**
     * 查询某个心理咨询师的客户数量
     *
     * @param userId: 用户编码
     * @return java.lang.Integer
     * @author He Peng
     * @date 2021/9/8 15:39
     */
    private Integer countCustomer(Long userId) {
        List<Integer> tmp = (List<Integer>) Execute.execute(Execute.QUERY_TYPE,
                CUSTOMER_MAPPER_ADDRESS + "countCustomer", new Object[]{userId});
        Integer total = 0;
        if (tmp != null && tmp.size() > 0) {
            total = tmp.get(0);
        }
        return total;
    }

    /**
     * 通过客户编号获得客户信息
     *
     * @param customerId:
     * @return com.bluedot.www.core.pojo.DO.Customer
     * @author ZhouXuan
     * @date 2021/9/2 17:49
     */
    private CustomerDTO findById(Long customerId) {
        CustomerDTO customerDTO = new CustomerDTO();
        // 通过编号获得客户信息
        List<Customer> customers = (List<Customer>) Execute.execute(Execute.QUERY_TYPE, CUSTOMER_MAPPER_ADDRESS + "findById", new Object[]{customerId});
        // 通过编号获得客户的家庭信息
        List<FamilyNumber> familyNumbers = (List<FamilyNumber>) Execute.execute(Execute.QUERY_TYPE, FAMILY_NUMBER_MAPPER_ADDRESS + "listFamilyNumberByCustomerId", new Object[]{customerId});

        customerDTO.setCustomer(customers.size() !=0 ? customers.get(0) : null);
        customerDTO.setFamilyNumbers(familyNumbers);

        return customerDTO;
    }

    /**
     * 保存客户（添加客户），成功之后，再调用增加家庭成员方法
     *
     * @param customer: 客户信息
     * @return java.lang.Long 返回客户编号
     * @author ZhouXuan
     * @date 2021/9/2 19:02
     */
    private Long insertCustomer(Customer customer) {
        // 添加客户信息
        // 设置客户主键
        Long customerId = DbUtil.generateId();
        customer.setId(customerId);

        // 设置创建时间和修改时间
        customer.setGmtCreate(DbUtil.getCurrentTime());
        customer.setGmtModified(DbUtil.getCurrentTime());

        Integer count = (Integer) Execute.execute(Execute.UPDATE_TYPE, CUSTOMER_MAPPER_ADDRESS + "insertCustomer", new Object[]{customer});

        boolean flag = count > 0 ? true : false;

        // 如果添加成功，则返回客户编号，否则返回null
        return flag ? customerId : null;
    }


    /**
     * 删除客户【若删除客户，并删除客户的家庭成员信息、分析报告、笔迹图片、笔迹特征】
     *
     * @param customerIds: 客户编号列表，若大小为1，则单个删除；若大小>1，则批量删除
     * @return void
     * @author ZhouXuan
     * @date 2021/8/8 9:42
     */
    private boolean deleteCustomer(List<Long> customerIds) {
        // 删除客户表中的数据
        boolean flag1 = true;

        Integer sum = 0;
        Integer count;
        for (Long customerId : customerIds) {
            count = (Integer) Execute.execute(Execute.UPDATE_TYPE, CUSTOMER_MAPPER_ADDRESS + "deleteCustomer", new Object[]{customerId});
            sum += count;
        }

        if (sum != customerIds.size()) {
            flag1 = false;
        }


        // 删除家庭成员中的数据
        boolean flag2 = true;
        for (Long customerId : customerIds) {
            // 应该查出此客户的家庭成员的数量进行判断，是否全部删除成功
            List<FamilyNumber> familyNumbers = (List<FamilyNumber>) Execute.execute(Execute.QUERY_TYPE, FAMILY_NUMBER_MAPPER_ADDRESS + "listFamilyNumberByCustomerId", new Object[]{customerId});

            Integer count2 = (Integer) Execute.execute(Execute.UPDATE_TYPE, FAMILY_NUMBER_MAPPER_ADDRESS + "deleteFamilyNumber", new Object[]{customerId});

            // 如果家庭成员删除失败，则标志置为false，并跳出循环
            if (familyNumbers.size() != count2) {
                flag2 = false;
                break;
            }
        }

        // 分析报告、笔迹图片、笔迹特征

        return (flag1 && flag2);

    }

    /**
     * 修改客户信息,之后再调用家庭成员信息修改
     *
     * @param customer:
     * @return java.lang.String
     * @author ZhouXuan
     * @date 2021/9/2 19:29
     */
    private boolean updateCustomer(Customer customer) {
        // 通过客户编号更新，客户信息（客户编号，放到隐藏域中）
        Integer count = (Integer) Execute.execute(Execute.UPDATE_TYPE, CUSTOMER_MAPPER_ADDRESS + "updateCustomer", new Object[]{customer});
        return count > 0;
    }


    /**
     * 移动客户所在的分组，通过更新客户的分组编号移动
     *
     * @param customerIds: 客户编号
     * @param groupId:     分组编号
     * @return boolean
     * @author ZhouXuan
     * @date 2021/9/2 14:58
     */
    private boolean moveCustomer(List<Long> customerIds, Long groupId) {
        HashMap<String, String> map1 = null;
        HashMap<String, String> map2 = null;

        Integer sum = 0;
        Integer count;
        for (Long customerId : customerIds) {
            map1 = new HashMap<>();
            map2 = new HashMap<>();
            map1.put("id", customerId.toString());
            map2.put("groupId", groupId.toString());
            count = (Integer) Execute.execute(Execute.UPDATE_TYPE, CUSTOMER_MAPPER_ADDRESS + "moveCustomer", new Object[]{map1, map2});
            sum += count;
        }

        return sum == customerIds.size() ? true : false;
    }

    /**
     * 通过客户编号，查看客户详细信息
     *
     * @param customerId: 客户编号
     * @return com.bluedot.www.core.pojo.VO.ViewUserInfo
     * @author ZhouXuan
     * @date 2021/8/8 9:36
     */
    private ViewCustomerInfo getCustomerInfo(int customerId) {
        return null;
    }

    /**
     * 查找心理咨询师某一分组的所有客户
     *
     * @param groupId: 客户编号
     * @return java.util.List<com.bluedot.www.core.pojo.DO.Customer>
     * @author ZhouXuan
     * @date 2021/8/8 9:58
     */
    private List<Customer> getCustomersByGroup(int groupId) {
        return null;
    }


    /**
     * 分析未分析客户笔迹图片【预处理图片展示下一步之后，再将图片存储到数据库】
     *
     * @param ids:                  客户编号列表，若大小为1，则单个分析；若大小>1，则批量分析
     * @param reportContentOption:  报告内容选项，'笔迹特征、性格分析、卡氏测定、职业建议'，选择的通过'，'隔开
     * @param preHandleAlgorithmId: 预处理算法编号
     * @param analysisAlgorithmId:  性格分析算法编号
     * @return boolean
     * @author ZhouXuan
     * @date 2021/8/8 10:49
     */
    private boolean analysisNotAnalysisCustomer(List<Integer> ids, String reportContentOption, int preHandleAlgorithmId, int analysisAlgorithmId) {
        return false;
    }


    /**
     * 分析客户未分析记录【预处理图片展示下一步之后，再将图片存储到数据库】
     *
     * @param characterReportIds:   性格报告编号列表，若大小为1，则单个分析；若大小>1，则批量分析
     * @param reportContentOption:  报告内容选项，'笔迹特征、性格分析、卡氏测定、职业建议'，选择的通过'，'隔开
     * @param preHandleAlgorithmId: 预处理算法编号
     * @param analysisAlgorithmId:  性格分析算法编号
     * @return boolean
     * @author ZhouXuan
     * @date 2021/8/8 14:19
     */
    private boolean analysisNotAnalysisRecord(List<Integer> characterReportIds, String reportContentOption, int preHandleAlgorithmId, int analysisAlgorithmId) {
        return false;
    }





    /**
     * 删除客户记录（包括未分析记录和历史记录）【删除包括性格报告、笔迹图片、笔迹特征】
     *
     * @param characterReportIds: 报告编号列表，若大小为1，则单个删除；若大小>1，则批量删除
     * @return boolean
     * @author ZhouXuan
     * @date 2021/8/8 14:47
     */
    private boolean deleteAnalysisRecords(List<Integer> characterReportIds) {
        return false;
    }


    /**
     * 根据客户编号查询客户信息
     * @param id: 客户编号
     * @return com.bluedot.www.core.pojo.DO.Customer 如果未找到则返回 null
     * @author He Peng
     * @date 2021/10/27 15:54
     */
    private Customer findCustomerById(Long id) {
        List<Customer> list = (List<Customer>) Execute.execute(Execute.QUERY_TYPE,
                CUSTOMER_MAPPER_ADDRESS + "findCustomerById", new Object[]{id});
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 查询客户历史记录(可以分为已分析，未分析和所有)
     * @param customerId: 客户编号
     * @param status: 是否查询未分析的性格报告，-1：查询所有，0：表示查询已分析，1：表示查询未分析性格报告
     * @return java.util.List<com.bluedot.www.core.pojo.DTO.CustomerHistoryDTO>
     * @author He Peng
     * @date 2021/10/30 10:59
     */
    private CustomerHistoryDTO queryCustomerHistory(Long customerId, Integer status) {
        CustomerHistoryDTO customerHistoryDTO = new CustomerHistoryDTO();
        Customer customer = findCustomerById(customerId);
        if (customer == null) {
            return null;
        }
        customerHistoryDTO.setCustomerId(customerId);
        customerHistoryDTO.setName(customer.getName());
        customerHistoryDTO.setUserId(customer.getUserId());
        customerHistoryDTO.setSort(customer.getSort());
        // 表示为客户
        Integer type = 1;
        List<ReportHistoryDTO> reportHistoryList = getReportHistoryDTOS(customerId, status, type);
        customerHistoryDTO.setReportHistoryList(reportHistoryList);

        return customerHistoryDTO;
    }

    /**
     * 获取客户的性格报告
     * @param customerId: 客户编号
     * @param status: 状态
     * @param type: 类型
     * @return java.util.List<com.bluedot.www.core.pojo.DTO.ReportHistoryDTO>
     * @author He Peng
     * @date 2021/11/1 18:52
     */
    private List<ReportHistoryDTO> getReportHistoryDTOS(Long customerId, Integer status, Integer type) {
        List<ReportHistoryDTO> reportHistoryList = (List<ReportHistoryDTO>) CharacterReportService.execute(
                "queryReportHistoryCondition", new Object[]{customerId, type, status});
        return reportHistoryList;
    }

    /**
     * 根据客户编号改变客户状态
     * @param customerId: 客户编号
     * @param status: 客户状态 0：不存在未分析性格报告；1：存在性格报告编号
     * @return boolean
     * @author He Peng
     * @date 2021/11/1 18:32
     */
    private boolean updateCustomerStatus(Long customerId, Integer status) {
        Map<String, Object> customerIdMap = new HashMap<>(1);
        Map<String, Object> statusMap = new HashMap<>(1);
        customerIdMap.put("customerId", customerId);
        statusMap.put("status", status);
        Object[] params = new Object[]{customerIdMap, statusMap};
        int res = (int) Execute.execute(Execute.UPDATE_TYPE,
                CUSTOMER_MAPPER_ADDRESS + "updateCustomerStatus", params);
        return res > 0;
    }

    /**
     * 批量更新客户状态
     * @param customerIdList: 客户编号集合
     * @return boolean
     * @author He Peng
     * @date 2021/11/1 19:16
     */
    private boolean updateCustomerStatusList(List<Long> customerIdList) {
        Map<Long, Integer> map = new HashMap<>(customerIdList.size());
        for (Long id : customerIdList) {
            map.put(id, isContainNoAnalysisReport(id));
        }
        for (Map.Entry<Long, Integer> entry : map.entrySet()) {
            if (entry.getValue() > 0) {
                // 存在未分析性格报告
                updateCustomerStatus(entry.getKey(), 1);
            } else {
                // 不存在未分析性格报告
                updateCustomerStatus(entry.getKey(), 0);
            }
        }
        return true;
    }


    /**
     * 判断是否存在未分析性格报告
     * @param customerId: 客户编号
     * @return int 未分析性格报告的数量
     * @author He Peng
     * @date 2021/11/1 19:53
     */
    private int isContainNoAnalysisReport(Long customerId) {
        List<Integer> res = (List<Integer>) Execute.execute(Execute.QUERY_TYPE,
                CUSTOMER_MAPPER_ADDRESS + "isContainNoAnalysisReport", new Object[]{customerId});
        if (res.size() > 0) {
            return res.get(0);
        }
        return 0;
    }
}
